
from typing import Optional,List
from datetime import datetime
from sqlmodel import (
    SQLModel,Field,UniqueConstraint,Relationship
)

####通用表####
class BaseEntity(SQLModel):
    id:Optional[int] = Field(default=None,primary_key=True)
    create_time:Optional[datetime] = Field(default_factory=datetime.now)
    update_time:Optional[datetime] = Field(default_factory=datetime.now)


####关系表####
class UserRoleLink(SQLModel,table=True):
    __tablename__:str = "sys_user_role_link"
    user_id:Optional[int] = Field(default=None,foreign_key="sys_user.id",primary_key=True)
    role_id:Optional[int] = Field(default=None,foreign_key="sys_role.id",primary_key=True)

class RolePermissionLink(SQLModel,table=True):
    __tablename__:str = "sys_role_permission_link"
    role_id:Optional[int] = Field(default=None,foreign_key="sys_role.id",primary_key=True)
    permission_id:Optional[int] = Field(default=None,foreign_key="sys_permission.id",primary_key=True)

####用户表####

class UserBase(BaseEntity):
    username:str = Field(index=True,unique=True)
class User(UserBase,table=True):
    __tablename__:str = "sys_user"
    hashed_password:str
    roles:Optional[List["Role"]] = Relationship(back_populates="users",link_model=UserRoleLink)


####角色表####
class RoleBase(BaseEntity):
    role_name:str = Field(index=True,unique=True)
    role_desc:Optional[str] = Field(default=None)

class Role(RoleBase,table=True):
    __tablename__:str = "sys_role"
    users:Optional[List[User]] = Relationship(back_populates="roles",link_model=UserRoleLink)
    permissions:Optional[List["Permission"]] = Relationship(back_populates="roles",link_model=RolePermissionLink)

####权限表####
class PermissionBase(BaseEntity):
    resource:str = Field(index=True)
    action:Optional[str] = Field(index=True)

class Permission(PermissionBase,table=True):
    __tablename__:str = "sys_permission"
    __table_args__ = (
        UniqueConstraint("resource","action",name="un_resource_action"),
    )
    roles:Optional[List["Role"]] = Relationship(back_populates="permissions",link_model=RolePermissionLink)
